RegisterHotKey (user32)
Last changed: -86.11.174.174

.
Summary

C# Signature:

/// <summary> The RegisterHotKey function defines a system-wide hot key </summary>
/// <param name="hwnd">Handle to the window that will receive WM_HOTKEY messages  generated by the hot key.</param>
/// <param name="id">Specifies the identifier of the hot key.</param>
/// <param name="fsModifiers">Specifies keys that must be pressed in combination with the key  specified by the 'vk' parameter in order to generate the WM_HOTKEY message.</param>
/// <param name="vk">Specifies the virtual-key code of the hot key</param>
/// <returns><c>true</c> if the function succeeds, otherwise <c>false</c></returns>
/// <seealso cref="http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx"/>
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

VB Signature:

Public Declare Function RegisterHotKey Lib "user32" Alias "RegisterHotKey" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Boolean

VB.net Signature:

Declare Auto Function RegisterHotKey Lib "user32.dll" (Byval handle As IntPtr, ByVal id As Integer, ByVal fsModifier As UInt32, ByVal vk As UInt32) As Boolean

User-Defined Types:

None.

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

    public class WindowsShell
    {
        #region fields
        public static int MOD_ALT = 0x1;
        public static int MOD_CONTROL = 0x2;
        public static int MOD_SHIFT = 0x4;
        public static int MOD_WIN = 0x8;
        public static int WM_HOTKEY = 0x312;
        #endregion

        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private static int keyId;
        public static void RegisterHotKey(Form f, Keys key)
        {
            int modifiers = 0;

            if ((key & Keys.Alt) == Keys.Alt)
                modifiers = modifiers | WindowsShell.MOD_ALT;

            if ((key & Keys.Control) == Keys.Control)
                modifiers = modifiers | WindowsShell.MOD_CONTROL;

            if ((key & Keys.Shift) == Keys.Shift)
                modifiers = modifiers | WindowsShell.MOD_SHIFT;

            Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;        
            keyId = f.GetHashCode(); // this should be a key unique ID, modify this if you want more than one hotkey
            RegisterHotKey((IntPtr)f.Handle, keyId, (uint)modifiers, (uint)k);
        }

        private delegate void Func();

        public static void UnregisterHotKey(Form f)
        {
            try
            {
                UnregisterHotKey(f.Handle, keyId); // modify this if you want more than one hotkey
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }

    public partial class Form1 : Form, IDisposable
    {
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Keys k = Keys.A | Keys.Control;
            WindowsShell.RegisterHotKey(this, k);
        }

        // CF Note: The WndProc is not present in the Compact Framework (as of vers. 3.5)! please derive from the MessageWindow class in order to handle WM_HOTKEY
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if (m.Msg == WindowsShell.WM_HOTKEY)
                this.Visible = !this.Visible;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            WindowsShell.UnregisterHotKey(this);
        }
    }

Sample Code:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;

    /// <summary> This class allows you to manage a hotkey </summary>
    public class GlobalHotkeys : IDisposable
    {
        [DllImport( "user32", SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool RegisterHotKey (IntPtr hwnd, int id, uint fsModifiers, uint vk);
        [DllImport( "user32", SetLastError = true )]
        public static extern int UnregisterHotKey (IntPtr hwnd, int id);
        [DllImport( "kernel32", SetLastError = true )]
        public static extern short GlobalAddAtom (string lpString);
        [DllImport( "kernel32", SetLastError = true )]
        public static extern short GlobalDeleteAtom (short nAtom);

        public const int MOD_ALT = 1;
        public const int MOD_CONTROL = 2;
        public const int MOD_SHIFT = 4;
        public const int MOD_WIN = 8;

        public const int WM_HOTKEY = 0x312;

        public GlobalHotkeys()
        {
            this.Handle = Process.GetCurrentProcess().Handle;
        }

        /// <summary>Handle of the current process</summary>
        public IntPtr Handle;

        /// <summary>The ID for the hotkey</summary>
        public short HotkeyID { get; private set; }

        /// <summary>Register the hotkey</summary>
        public void RegisterGlobalHotKey(int hotkey, int modifiers, IntPtr handle)
        {
            UnregisterGlobalHotKey();
            this.Handle = handle;
            RegisterGlobalHotKey(hotkey, modifiers);
        }

        /// <summary>Register the hotkey</summary>
        public void RegisterGlobalHotKey(int hotkey, int modifiers)
        {
            UnregisterGlobalHotKey();

            try
            {
                // use the GlobalAddAtom API to get a unique ID (as suggested by MSDN)
                string atomName = Thread.CurrentThread.ManagedThreadId.ToString("X8") + this.GetType().FullName;
                HotkeyID = GlobalAddAtom(atomName);
                if (HotkeyID == 0)
                    throw new Exception("Unable to generate unique hotkey ID. Error: " + Marshal.GetLastWin32Error().ToString());

                // register the hotkey, throw if any error
                if (!RegisterHotKey(this.Handle, HotkeyID, (uint)modifiers, (uint)hotkey))
                    throw new Exception("Unable to register hotkey. Error: " + Marshal.GetLastWin32Error().ToString());

            }
            catch (Exception ex)
            {
                // clean up if hotkey registration failed
                Dispose();
                Console.WriteLine(ex);
            }
        }

        /// <summary>Unregister the hotkey</summary>
        public void UnregisterGlobalHotKey()
        {
            if ( this.HotkeyID != 0 )
            {
                UnregisterHotKey(this.Handle, HotkeyID);
                // clean up the atom list
                GlobalDeleteAtom(HotkeyID);
                HotkeyID = 0;
            }
        }

        public void Dispose()
        {
            UnregisterGlobalHotKey();
        }
    }

How to use :

GlobalHotkeys hotkey;

hotkey = new GlobalHotkeys();
hotkey.RegisterGlobalHotKey( (int) Keys.F11, GlobalHotkeys.MOD_CONTROL );
hotkey.UnregisterGlobalHotKey();

protected override void WndProc (ref Message m)
{
     const int WM_HOTKEY = 0x0312;

     switch ( m.Msg )
     {
      case WM_HOTKEY:
      {
           if ((short)m.WParam == hotkey.HotkeyID)
           {
            // do your thing
           }
           break;
      }
      default:
      {
           base.WndProc(ref m);
           break;
      }
     }
}

Alternative Managed API:

The ManagedWindowsApi project (http://mwinapi.sourceforge.net) provides a Hotkey class to register global hotkeys.

Documentation
Documentation